
Imports System.Windows.Forms
Imports System.ComponentModel
Imports System.Resources
Imports System.Drawing
Public Class ExTextBox
    Inherits System.Windows.Forms.TextBox
#Region "Constructors"
    Public Sub New()
      MyBase.New()
      InitializeComponent()
      m_BorderDrawer.BorderColor = m_BorderColor
    End Sub
#End Region
#Region " Attributes "

#Region " Fields "
    Private m_ValidationMode As ValidationModes
    Private m_BorderColor As Color = System.Drawing.SystemColors.GradientActiveCaption   'Color.FromArgb(127, 157, 185)
    Private m_ValidBorderColor As Color = System.Drawing.SystemColors.GradientActiveCaption  'Color.FromArgb(127, 157, 185)
    Private m_InvalidBorderColor As Color = Color.Red
    Private m_ValidData As Boolean = True
    Private m_Tooltip As String = "Please enter invalid data."
    Private m_BorderDrawer As BorderDrawer = New BorderDrawer()
    Friend WithEvents m_TooltipCtr As System.Windows.Forms.ToolTip
    Private m_MinValue As Double
    Private m_MaxValue As Double
    Private m_EnableNumberRange As Boolean = False
    Private m_EnableToolTip As Boolean = False
    Private m_CheckStringNull As Boolean = False
    Private Const WM_MOUSEOVER As Integer = &H200
#End Region 'Fields
#Region " Properties "
    <CategoryAttribute("Appearance"), DescriptionAttribute("Check String Null.")> _
     Public Property CheckStringNull() As Boolean
        Get
            Return m_CheckStringNull
        End Get
        Set(ByVal Value As Boolean)
            m_CheckStringNull = Value
        End Set
    End Property
    <CategoryAttribute("Appearance"), DescriptionAttribute("Enabe tool tip.")> _
     Public Property EnableTooltip() As Boolean
        Get
            Return m_EnableToolTip
        End Get
        Set(ByVal Value As Boolean)
            m_EnableToolTip = Value
        End Set
    End Property
    <CategoryAttribute("Appearance"), DescriptionAttribute("Enabe number range.")> _
     Public Property EnableNumberRange() As Boolean
        Get
            Return m_EnableNumberRange
        End Get
        Set(ByVal Value As Boolean)
            m_EnableNumberRange = Value
            If m_EnableNumberRange Then
                ValidationMode = ValidationModes.Numbers
                SelfCheckValidData()
            End If
        End Set
    End Property
    <CategoryAttribute("Appearance"), DescriptionAttribute("Min value.")> _
      Public Property MinValue() As Double
        Get
            Return m_MinValue
        End Get
        Set(ByVal Value As Double)
            m_MinValue = Value
            If ValidationMode <> ValidationModes.None Then
                SelfCheckValidData()
            End If
        End Set
    End Property
    <CategoryAttribute("Appearance"), DescriptionAttribute("Max value.")> _
      Public Property MaxValue() As Double
        Get
            Return m_MaxValue
        End Get
        Set(ByVal Value As Double)
            m_MaxValue = Value
            If ValidationMode <> ValidationModes.None Then
                SelfCheckValidData()
            End If
        End Set
    End Property
    <CategoryAttribute("Appearance"), DescriptionAttribute("Tool tip.")> _
    Public Property ToolTipContent() As String
        Get
            Return m_Tooltip
        End Get
        Set(ByVal Value As String)
            m_Tooltip = Value
        End Set
    End Property
    <CategoryAttribute("Appearance"), DescriptionAttribute("ToolTip control.")> _
    Public ReadOnly Property ToolTipCtr() As ToolTip
        Get
            Return m_TooltipCtr
        End Get
    End Property
    <CategoryAttribute("Appearance"), DescriptionAttribute("Border color.")> _
    Public Property BorderColor() As Color
        Get
            Return m_BorderColor
        End Get
        Set(ByVal Value As Color)
            m_BorderColor = Value
            m_BorderDrawer.BorderColor = m_BorderColor
            Invalidate()
        End Set
    End Property
    <CategoryAttribute("Appearance"), DescriptionAttribute("Valid border color.")> _
    Public Property ValidBorderColor() As Color
        Get
            Return m_ValidBorderColor
        End Get
        Set(ByVal Value As Color)
            If m_ValidBorderColor.Equals(Value) Then Return
            m_ValidBorderColor = Value
        End Set
    End Property
    <CategoryAttribute("Appearance"), DescriptionAttribute("Invalid border color.")> _
   Public Property InvalidBorderColor() As Color
        Get
            Return m_InvalidBorderColor
        End Get
        Set(ByVal Value As Color)
            If m_InvalidBorderColor.Equals(Value) Then Return
            m_InvalidBorderColor = Value
        End Set
    End Property
    <CategoryAttribute("Appearance"), DescriptionAttribute("Valid data.")> _
    Public Property ValidData() As Boolean
        Get
            Return m_ValidData
        End Get
        Set(ByVal Value As Boolean)
            m_ValidData = Value
            If m_ValidData Then
                BorderColor = m_ValidBorderColor
            Else
                BorderColor = m_InvalidBorderColor
            End If
        End Set
    End Property
    Enum ValidationModes
        None = 0
        Numbers = 1
        Strings = 2
    End Enum
    <Description("Sets the validation mode to use."), Category("Validation"), RefreshProperties(RefreshProperties.All)> _
    Public Overridable Property ValidationMode() As ValidationModes
        Get
            Return m_ValidationMode
        End Get
        Set(ByVal Value As ValidationModes)
            m_ValidationMode = Value
        End Set
    End Property
#End Region 'Properties

#End Region 'Attributes

#Region " Methods "
    Protected Overrides Sub WndProc(ByRef m As Message)
      MyBase.WndProc(m)
        If ValidationMode <> ValidationModes.None AndAlso Not ValidData Then
            m_BorderDrawer.DrawBorder(m, Me.Width, Me.Height)
        End If
    End Sub
    Private Sub TextChanged_TextBoxEx(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.TextChanged
      If ValidationMode <> ValidationModes.None Then
          SelfCheckValidData()
      End If
    End Sub
     Protected Overrides Sub OnLostFocus(ByVal e As System.EventArgs)
        If Not Me.ReadOnly Then
            MyBase.OnLostFocus(e)
        End If
        ToolTipCtr.Hide(Me)
    End Sub
    Protected Overrides Sub OnReadOnlyChanged(ByVal e As System.EventArgs)
        If Me.ReadOnly Then
            Me.TextAlign = HorizontalAlignment.Center
            Me.BackColor = SystemColors.ControlLight
            Me.BackColor = SystemColors.Control
        Else
            Me.BackColor = SystemColors.Window
        End If
        MyBase.OnReadOnlyChanged(e)
    End Sub
    Protected Overrides Sub OnGotFocus(ByVal e As System.EventArgs)
        If Not Me.ReadOnly Then
            MyBase.OnGotFocus(e)
        End If
        If Not ValidData Then
            ShowToolTip(True)
        End If
    End Sub
    Protected Overrides Sub OnClick(ByVal e As System.EventArgs)
        If Not Me.ReadOnly Then
            MyBase.OnClick(e)
        End If
    End Sub
    Protected Overridable Function SelfCheckValidData() As Boolean
        Dim Validate As Boolean = False
        Dim Value As Double = 0.0
        If (Me.Text.Trim() = String.Empty And Not CheckStringNull) Or Me.ReadOnly Then
            Validate = True
            ToolTipCtr.Hide(Me)
        Else
            Select Case ValidationMode
                Case ValidationModes.Numbers 'NUMBERS
                    Try
                        Validate = IsNumeric(Me.Text.Trim())
                        Value = Double.Parse(Me.Text.Trim())
                    Catch ex As Exception
                        Validate = False
                        If m_MinValue <= m_MaxValue AndAlso m_EnableNumberRange Then
                            ToolTipContent = "  " + m_MinValue.ToString() + "..." + m_MaxValue.ToString() + "  "
                            ShowToolTip(True)
                        End If
                    End Try
                Case ValidationModes.Strings 'STRING
                    Validate = True
            End Select
            If m_MinValue <= m_MaxValue AndAlso m_EnableNumberRange Then
                If Validate Then
                    If Value < m_MinValue Or Value > m_MaxValue Then
                        Validate = False
                    Else
                        Validate = True
                    End If
                End If
                If m_EnableToolTip Then
                    If Not Validate Then
                        ToolTipContent = "  " + m_MinValue.ToString() + "..." + m_MaxValue.ToString() + "  "
                        ShowToolTip(True)
                    Else
                        ToolTipCtr.Hide(Me)
                    End If
                End If
            End If
        End If
        ValidData = Validate
        If Validate Then
            SendMessage(Handle, WM_MOUSEOVER, 0, 0)
        End If
        Return Validate
    End Function

#End Region 'Methods

    Private Sub ValidTextBox_Layout(ByVal sender As System.Object, ByVal e As System.Windows.Forms.LayoutEventArgs) Handles MyBase.Layout
        If ValidationMode <> ValidationModes.None Then
            SelfCheckValidData()
        End If
    End Sub
    Public Sub ShowToolTip(ByVal bShow As Boolean)
        If bShow Then
            ToolTipCtr.SetToolTip(Me, ToolTipContent)
            ToolTipCtr.Show(ToolTipContent, Me, Me.ClientRectangle.Right, Me.ClientRectangle.Top - Me.ClientRectangle.Height)
        Else
            ToolTipCtr.Hide(Me)
        End If
    End Sub
    Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
End Class
